"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const word_1 = require("./lib/word");
// 示例中的部分关键词、运算符、分隔符
// 加载JavaScript代码
const code = fs.readFileSync('./test/testCode.js', 'utf-8');
/**
 * 词法分析器函数
 * 对输入的JavaScript代码字符串进行分析，生成Token数组。
 *
 * @param input 输入的JavaScript代码字符串。
 * @returns 生成的Token数组，每个Token代表代码中的一个最小单位，如关键词、运算符、标识符等。
 */
function tokenize(input) {
    // 初始化位置变量和用于存储生成Token的数组
    let position = 0;
    const tokens = [];
    // 遍历输入代码字符串，直到处理完所有字符
    while (position < input.length) {
        // 跳过并前进到下一个非空白字符
        if (/\s/.test(input[position])) {
            position++;
            continue;
        }
        // 检查当前字符是否位于预定义关键词列表中，如果是则生成对应的Token
        if (word_1.keywords.some((keyword) => input.startsWith(keyword, position))) {
            const keyword = word_1.keywords.find((k) => input.startsWith(k, position));
            tokens.push({ kind: 'keyword', value: keyword });
            position += keyword.length;
            continue;
        }
        // 检查当前字符是否是预定义运算符之一，如果是则生成对应的Token
        if (word_1.operators.some((op) => input[position] === op)) {
            const operator = input[position];
            tokens.push({ kind: 'operator', value: operator });
            position++;
            continue;
        }
        // 检查当前字符是否是预定义的分隔符之一，如果是则生成对应的Token
        if (word_1.delimiters.some((delim) => input[position] === delim)) {
            const delimiter = input[position];
            tokens.push({ kind: 'delimiter', value: delimiter });
            position++;
            continue;
        }
        // 处理字符串：找到字符串开始的引号，读取并生成Token
        if (input[position] === '"' || input[position] === "'") {
            const quote = input[position++];
            let stringValue = '';
            // 循环读取直到遇到与开始引号相匹配的结束引号
            while (input[position] !== quote && position < input.length) {
                stringValue += input[position++];
            }
            // 验证是否成功找到结束引号并生成Token
            if (input[position] === quote) {
                position++; // 移动到下一个字符，跳过结束引号
                tokens.push({ kind: 'string', value: stringValue });
            }
            else {
                throw new Error('Unterminated string');
            }
            continue;
        }
        // 处理标识符：从字母、下划线或美元符号开始，连续读取符合标识符规则的字符并生成Token
        if (/^[a-zA-Z_$]/.test(input[position])) {
            let identifier = '';
            while (/^[a-zA-Z0-9_$]/.test(input[position]) &&
                position < input.length) {
                identifier += input[position++];
            }
            tokens.push({ kind: 'identifier', value: identifier });
            continue;
        }
        // 处理数字：检查当前位置是否存在数字，提取并生成Token
        if (/^-?[0-9]+(\.[0-9]*)?$/g.test(input[position])) {
            const numberMatch = /^-?[0-9]+(\.[0-9]*)?/.exec(input.slice(position));
            // 如果找到了数字表达式，将其转换为浮点数并生成Token
            if (numberMatch) {
                const numberValue = parseFloat(numberMatch[0]);
                tokens.push({ kind: 'number', value: numberValue });
                position += numberMatch[0].length;
            }
            continue;
        }
        // 处理单行注释：找到以'//'开始的注释并生成Token
        if (input.substring(position, position + 3) === '//') {
            let endOfLine = input.indexOf('\n', position);
            // 若在行尾未找到换行符，则表示注释至字符串末尾
            if (endOfLine === -1) {
                endOfLine = input.length;
            }
            tokens.push({
                kind: 'comment',
                value: input.slice(position + 2, endOfLine),
            });
            position = endOfLine;
            continue;
        }
        // 处理多行注释：找到以'/*'开始的注释并生成Token
        if (input.substring(position, 2) === '/*') {
            let endOfComment = input.indexOf('*/', position + 2);
            // 若未找到注释结束符，则抛出错误
            if (endOfComment === -1) {
                throw new Error('Unterminated multi-line comment');
            }
            tokens.push({
                kind: 'comment',
                value: input.slice(position + 2, endOfComment),
            });
            position = endOfComment + 2;
            continue;
        }
        // 当前位置的字符无法识别时，抛出错误
        throw new Error(`Unrecognized token << ${input[position]} >> at position ${position}`);
    }
    // 返回生成的Token数组
    return tokens;
}
// 使用示例
try {
    const tokens = tokenize(code);
    console.log(tokens);
}
catch (error) {
    console.error(error.message);
}
